<template>
  <el-row class="hotel-detail__area-info" type="flex">
    <div class="map" id="map"></div>
    <div class="area-info" id="areaInfo">
      <el-tabs v-model="activeName" @tab-click="switchTab">
        <el-tab-pane label="风景" name="scenic">
          <ol class="area-info-list" v-if="scenics.length > 0">
            <li
              class="area-info-list__item"
              v-for="scenic in scenics"
              :key="scenic.id"
              @mouseover="hoverTabItem(scenic)"
            >
              <span class="name">{{ scenic.name }}</span>
              <span class="distance">{{ scenic.distance / 1000 }}公里</span>
            </li>
          </ol>
        </el-tab-pane>
        <el-tab-pane label="交通" name="traffic">
          <ol class="area-info-list" v-if="stations.length > 0">
            <li
              class="area-info-list__item"
              v-for="station in stations"
              :key="station.id"
              @mouseover="hoverTabItem(station)"
            >
              <span class="name">{{ station.name }}</span>
              <span class="distance">{{ station.distance / 1000 }}公里</span>
            </li>
          </ol>
        </el-tab-pane>
      </el-tabs>
    </div>
  </el-row>
</template>

<script>
export default {
  name: 'HotelDetailAreaInfo',
  props: {
    hotelAreaInfo: {
      type: Object,
      default () {
        return {
          longitude: undefined,
          latitude: undefined,
          name: undefined,
          address: undefined
        }
      }
    }
  },
  data () {
    return {
      map: {},
      mapUrl: 'https://webapi.amap.com/maps?v=1.4.15&key=a3bef07558c5ea956fe1aa766fac3400&callback=loadMap',
      activeName: 'scenic',
      scenics: [],
      stations: [],
      markers: [],
      hotelMarker: {}
    }
  },
  methods: {
    loadMap () {
      this.map = new AMap.Map('map', {
        resizeEnable: true,
        zoom: 10
      })
      this.$emit('load-map')
    },
    loadMapScript () {
      const amapScript = document.createElement('script')
      amapScript.src = this.mapUrl
      document.head.appendChild(amapScript)
    },
    /**
     * 渲染标记
     * @param {Object} option 配置对象
     * @param {string} option.icon 标记的图标
     * @param {string} option.title 标记悬停时的显示内容
     * @param {string} option.content 标记文本
     * @param {Object} option.position 标记位置
     */
    renderMark (option) {
      const marker = new AMap.Marker({
        map: this.map,
        ...option
      })

      const infoWindow = new AMap.InfoWindow({
        offset: new AMap.Pixel(0, -35),
        content: option.title
      })

      marker.on('mouseover', e => {
        infoWindow.open(this.map, e.target.getPosition())
        this.map.setCenter(option.position)
      })

      marker.on('mouseout', () => {
        infoWindow.close()
      })

      this.map.setFitView()

      return marker
    },
    searchScenics (keyword) {
      // 由于酒店的坐标不对，需要对酒店的地址进行搜索，搜索结果的第1项就是酒店坐标
      const p = new Promise(rv => {
        AMap.plugin('AMap.PlaceSearch', () => {
          //构造地点查询类
          const placeSearch = new AMap.PlaceSearch({
            type: '风景名胜',
            autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
          })
          placeSearch.search(keyword, (status, result) => {
            if (status === 'complete' && result.info === 'OK') {
              rv(result)
            }
          })
        })
      })
      return p
    },
    searchStation (keyword) {
      const p = new Promise(rv => {
        AMap.plugin('AMap.StationSearch', () => {
          const station = new AMap.StationSearch({
            pageIndex: 1,
            pageSize: 10
          })

          station.search(keyword, (status, result) => {
            if (status === 'complete' && result.info === 'OK') {
              rv(result)
            }
          })
        })
      })
      return p
    },

    /**
     * 对位置点进行排序
     * @param {Object[]} pois 位置列表
     * @returns {Array} 排序后的位置列表
     */
    sortPois (pois) {
      pois = pois.map((poi, index) => {
        const marker = this.renderMark({
          position: poi.location,
          title: poi.name
        })

        // 计算酒店标记点与其它标记点的距离
        const p1 = this.hotelMarker.getPosition()
        const p2 = marker.getPosition()
        const distance = Math.round(p1.distance(p2))
        poi.distance = distance

        this.markers.push(marker)
        this.markers[index].distance = distance

        return poi
      })

      pois.sort((a, b) => a.distance - b.distance)
      this.markers.sort((a, b) => a.distance - b.distance)

      // 排序完再设置标记序号
      this.markers.forEach((marker, index) => {
        const content = this.getMarkerContent(index + 1)
        marker.setContent(content)
      })

      return pois
    },
    async renderScenics (keyword) {
      const  result = await this.searchScenics(keyword)

      const scenics = result.poiList.pois.slice(1)

      this.scenics = this.sortPois(scenics)
    },
    async renderStations (keyword) {
      const result = await this.searchStation(keyword)

      this.stations = this.sortPois(result.stationInfo)
    },
    switchTab (tab) {
      const keyword = this.hotelAreaInfo.address
      this.map.remove(this.markers)
      this.map.clearInfoWindow()
      this.markers = []
      switch (tab.label) {
        case '风景':
          this.renderScenics(keyword)
          break
        case '交通':
          this.renderStations(keyword)
          break
      }
    },
    getMarkerContent (content) {
      return `<span class="custom-marker">${content}</span>`
    },
    hoverTabItem (scenic) {
      const infoWindow = new AMap.InfoWindow({
        offset: new AMap.Pixel(0, -35),
        content: scenic.name,
        position: scenic.location
      })

      infoWindow.open(this.map)
      this.map.setCenter(scenic.location)
    }
  },
  watch: {
    async hotelAreaInfo ({ name, address }) {
      // 先生成酒店的标记
      const result = await this.searchScenics(address)
      const hotel = result.poiList.pois[0]

      this.hotelMarker = this.renderMark({
        position: hotel.location,
        title: name,
        icon: require('@/assets/images/mark_b.png')
      })

      this.renderScenics(address)
    }
  },
  mounted () {
    window.loadMap = this.loadMap
    this.loadMapScript()
  }
}
</script>

<style>
.amap-icon img{
  width: 22px;
  height: 36px;
}
.amap-info-content {
  font-size: 12px;
}
.custom-marker {
  display: inline-block;
  width: 22px;
  height: 36px;
  text-align: center;
  line-height: 24px;
  font-size: 12px;
  color: #fff;
  background-size: 22px 36px;
  background-image: url(https://webapi.amap.com/theme/v1.3/markers/b/mark_bs.png);
}
</style>

<style lang="less" scoped>
.hotel-detail__area-info {
  height: 360px;
  margin-bottom: 40px;
  .map {
    width: 65%;
  }
  .area-info {
    margin-left: 20px;
    flex: 1;
    &-list {
      height: 300px;
      overflow: auto;
      font-size: 14px;
      color: #666;
      &__item {
        display: flex;
        justify-content: space-between;
        padding: 0 20px 0 10px;
        margin-bottom: 20px;
        cursor: pointer;
      }
    }
  }
}
</style>
